/*
 * MainFrame.java
 *
 * Created on 13 maart 2008, 14:18
 */
package view.GUI;

import view.GUI.sidepanels.PropertiesPanel;
import controller.Reflect;
import controller.Controller;
import controller.Serializer;
import controller.StdDraw;
import controller.commands.ImportBoxNodeCommand;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;
import javax.swing.BoxLayout;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.JViewport;
import javax.swing.border.LineBorder;
import model.graphic.objects.GBoxNode;
import model.graphic.objects.GNode;
import model.graphic.objects.GTrigger;
import model.graphic.objects.Graphical;
import view.GUI.sidepanels.CustomArgument;
import view.GUI.actions.DeleteAction;
import view.GUI.listeners.DropListener;
import view.GUI.graphic.GraphicView;

/**
 *
 * @author  wijnand.schepens@hogent.be
 */
public class MainFrame extends javax.swing.JFrame implements MouseMotionListener {

    private Controller controller;
    private JToolBar toolbar;
    private JMenuBar menubar;
    private JTextArea debug;
    private JScrollPane scroll;
    private JViewport viewport;
    private JPanel main,  maingraphic,  mainright,  mainunder;
    private PropertiesPanel props;
    private JFileChooser filechooser;
    private JSplitPane splitPane;
    private JSplitPane splitPane2;
    private JPanel mainunderstroke;
    private JTextArea ta;
    private JSplitPane splitPane3;

    public MainFrame(Controller controller) {
        this.controller = controller;
        this.props = controller.getPropertiesPanel();
        this.toolbar = controller.getToolbar();
        this.menubar = new JMenuBar();
        this.debug = controller.getDebug();
        this.viewport = new JViewport();
        this.main = new JPanel();
        this.mainright = new JPanel();
        this.maingraphic = new JPanel();
        this.mainunder = new JPanel();
        this.filechooser = new JFileChooser(".");
        this.mainunderstroke = new JPanel();

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        this.getContentPane().setLayout(new BorderLayout());
        main.setLayout(new BoxLayout(main, 0));

        mainunder.setLayout(new BorderLayout());

        ta = new JTextArea(LabelReader.getInstance().getString("Welcome"));
        ta.setEditable(false);
        ta.setLineWrap(true);
        ta.setWrapStyleWord(true);
        ta.setBackground(new Color(240, 240, 240));
        Font f = new Font("Arial", Font.PLAIN, 11);
        ta.setFont(f);
        ta.setMinimumSize(new Dimension(180, 100));

        JTabbedPane tabUnder = new JTabbedPane();
        tabUnder.addTab(LabelReader.getInstance().getString("Output"), new JScrollPane(controller.getOutput(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
        tabUnder.addTab(LabelReader.getInstance().getString("Debug"), new JScrollPane(controller.getDebug(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
        tabUnder.addTab(LabelReader.getInstance().getString("Drawing"), new JScrollPane(controller.getDrawPanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
        controller.getStatusbar().setMaximumSize(new Dimension(4000, 50));
        mainunder.add(tabUnder, BorderLayout.CENTER);
        mainunderstroke.setLayout(new BoxLayout(mainunderstroke, BoxLayout.X_AXIS));
        mainunderstroke.add(controller.getStatusbar(), BorderLayout.SOUTH);
        JLabel ri = new JLabel(new ResizeIcon());
        Cursor c = ri.getCursor();
        ri.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
        ri.addMouseMotionListener(this);
        mainunderstroke.add(ri);
        mainunder.add(mainunderstroke);

        DropListener drop = new DropListener(maingraphic, controller.getGview());

        initMenu();

        this.getContentPane().add(toolbar, BorderLayout.NORTH);
        this.getContentPane().add(main, BorderLayout.CENTER);
        this.getContentPane().add(mainunder, BorderLayout.SOUTH);

        GraphicView gv = controller.getGview();
        scroll = new JScrollPane(gv, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scroll.setSize(200, 200);

        maingraphic.setLayout(new BorderLayout());
        maingraphic.setBorder(new LineBorder(Color.GRAY));
        maingraphic.setMinimumSize(new Dimension(550, 550));
        initGraphicView();

        mainunder.setLayout(new BoxLayout(mainunder, BoxLayout.Y_AXIS));
        mainunder.setMinimumSize(new Dimension(500, 130));
        mainunder.setMaximumSize(new Dimension(2000, 200));
        controller.getTabRight().setPreferredSize(new Dimension(180, 550));
        controller.getTabRight().setMinimumSize(new Dimension(180, 250));
        controller.getPalette().addInfoPanelRef(ta);

        splitPane3 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controller.getTabRight(), ta);
        splitPane3.setOneTouchExpandable(true);
        splitPane3.setDividerLocation(350);
        splitPane3.setResizeWeight(1);
        splitPane3.setDividerSize(8);
        splitPane3.setBorder(null);

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                maingraphic, splitPane3);
        splitPane.setOneTouchExpandable(true);
        splitPane.setDividerLocation(725);
        splitPane.setResizeWeight(1);
        splitPane.setDividerSize(8);
        mainright.setMinimumSize(new Dimension(180, 250));

        splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                splitPane, mainunder);
        splitPane2.setOneTouchExpandable(true);
        splitPane2.setDividerLocation(450);
        splitPane2.setResizeWeight(1);
        splitPane2.setDividerSize(8);


        main.add(splitPane2);

        this.setPreferredSize(new Dimension(1000, 700));

        Reflect r = new Reflect(controller.getGmodel(), controller.getPalette());
        r.initLoad();
    }

    private void initMenu() {
        JMenu menuFile = new JMenu(LabelReader.getInstance().getString("File"));
        JMenu menuEdit = new JMenu(LabelReader.getInstance().getString("Edit"));
        JMenu menuPalette = new JMenu(LabelReader.getInstance().getString("Palette"));
        JMenu menuHelp = new JMenu(LabelReader.getInstance().getString("Help"));

        JMenuItem mItemNew = new JMenuItem(new DeleteAction(true, controller.getGview()));
        mItemNew.setText(LabelReader.getInstance().getString("New"));
        JMenuItem mItemOpen = new JMenuItem(LabelReader.getInstance().getString("Open"));
        JMenuItem mItemSaveAs = new JMenuItem(LabelReader.getInstance().getString("SaveAs"));
        JMenuItem mItemJPG = new JMenuItem(LabelReader.getInstance().getString("Export"));
        JMenuItem mItemExit = new JMenuItem(LabelReader.getInstance().getString("Exit"));
        JMenuItem mItemLoad = new JMenuItem(LabelReader.getInstance().getString("ImportNode"));
        JMenuItem mItemBoxLoad = new JMenuItem(LabelReader.getInstance().getString("ImportBoxNode"));
        JMenuItem mItemModifySkin = new JMenuItem(LabelReader.getInstance().getString("ModifySkin"));
        JMenuItem mItemModifyDelay = new JMenuItem(LabelReader.getInstance().getString("ModifyDelay"));
        JMenuItem mItemHelp = new JMenuItem(LabelReader.getInstance().getString("Help"));
        JMenuItem mItemAbout = new JMenuItem(LabelReader.getInstance().getString("About"));

        mItemHelp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MainFrame.this, LabelReader.getInstance().getString("HelpText"), LabelReader.getInstance().getString("Help"), JOptionPane.INFORMATION_MESSAGE);
            }
        });

        mItemAbout.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                
                JOptionPane.showMessageDialog(MainFrame.this, LabelReader.getInstance().getString("AboutText"), LabelReader.getInstance().getString("About"), JOptionPane.INFORMATION_MESSAGE);
            }
        });

        mItemExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        mItemModifySkin.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                SkinChooser skinChooser = new SkinChooser(controller.getGmodel(),scroll);
            }
        });

        mItemModifyDelay.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String time = JOptionPane.showInputDialog(LabelReader.getInstance().getString("EnterDelay"));
                try{
                    int delay = Integer.parseInt(time);
                    StdDraw.getInstance().getTurtle().setDelay(delay);
                }catch(Exception ex){
                    JOptionPane.showMessageDialog(null,"MainFrame:" + ex.getMessage(),LabelReader.getInstance().getString("Error"),JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        mItemSaveAs.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if(controller.getGmodel().isMainTriggerSet()){
                    filechooser.setFileFilter(new ConnectFileFilter(".ct (Connect)", new String[]{"ct", "connect"}));
                    int returnVal = filechooser.showSaveDialog(MainFrame.this);
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        File file = filechooser.getSelectedFile();
                        if (file.getPath().endsWith(".ct")) {
                            Serializer s = new Serializer(controller.getGmodel(), controller.getCmodel(), file.getPath());
                            s.serialize();
                        } else {
                            Serializer s = new Serializer(controller.getGmodel(), controller.getCmodel(), file.getPath() + ".ct");
                            s.serialize();
                        }

                    }
                    controller.getGview().repaint();
                    controller.getGview().updateUI();
                }else{
                    JOptionPane.showMessageDialog(null, LabelReader.getInstance().getString("SetMainTriggerSaveError"), LabelReader.getInstance().getString("Error"),JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });

        mItemOpen.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                filechooser.setFileFilter(new ConnectFileFilter(".ct (Connect)", new String[]{"ct", "connect"}));
                int returnVal = filechooser.showOpenDialog(MainFrame.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = filechooser.getSelectedFile();
                    Serializer s = new Serializer(controller.getGmodel(), controller.getCmodel(), file.getPath());
                    s.deserialize();
                }
                controller.getGview().removeAll();
                controller.getGmodel().getAllNodes().clear();
                controller.getGview().repaint();
                controller.getGview().updateUI();
                for (Graphical g : controller.getGmodel().getObjects()) {
                    System.out.println(g.getClass());
                    controller.getGview().add(g);
                    if (GNode.class.isAssignableFrom(g.getClass())) {
                        controller.getGmodel().getAllNodes().add(g);
                    }
                    if (GBoxNode.class.isAssignableFrom(g.getClass())) {
                        GBoxNode bn = (GBoxNode) g;
                        for (Graphical gt : bn.getTransmitterObjects()) {
                            controller.getGview().add(gt);
                            if (GTrigger.class.isAssignableFrom(gt.getClass())) {
                                GTrigger trigger = (GTrigger) gt;
                                System.out.println(trigger.getBaseColor());
                                if (trigger.getBackColor().equals(Color.GREEN)) {
                                    controller.getGmodel().setMainTrigger(trigger);
                                }
                            }
                        }
                        for (Graphical gi : bn.getInternalObjects()) {
                            controller.getGview().add(gi);
                            if (GTrigger.class.isAssignableFrom(gi.getClass())) {
                                GTrigger trigger = (GTrigger) gi;
                                System.out.println(trigger.getBaseColor());
                                if (trigger.getBackColor().equals(Color.GREEN)) {
                                    controller.getGmodel().setMainTrigger(trigger);
                                }
                            }
                        }
                    }
                    if (GTrigger.class.isAssignableFrom(g.getClass())) {
                        GTrigger trigger = (GTrigger) g;
                        if (trigger.getBackColor().equals(Color.GREEN)) {
                            controller.getGmodel().setMainTrigger(trigger);
                        }
                    }

                }
                controller.getGview().notifyObservers(new CustomArgument("tabRight", 1));

            }
        });

        mItemJPG.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                filechooser.setFileFilter(new ConnectFileFilter(".jpg (" + LabelReader.getInstance().getString("Image") +")", new String[]{"jpg", "jpeg"}));
                int returnVal = filechooser.showSaveDialog(MainFrame.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = filechooser.getSelectedFile();
                    if(!file.getPath().endsWith(".jpg")){
                        file = new File(file.getPath() + ".jpg");
                    }
                    controller.getGview().saveToJPG(file);
                }
            }
        });

        mItemLoad.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                filechooser.setFileFilter(new ConnectFileFilter(".java (Java file)", new String[]{"java", "Java file"}));
                int returnVal = filechooser.showOpenDialog(MainFrame.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = filechooser.getSelectedFile();
                    Reflect r = new Reflect(controller.getGmodel(), controller.getPalette());
                    r.importNode(file);
                }
            }
        });

        mItemBoxLoad.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                filechooser.setFileFilter(new ConnectFileFilter(".bn (BoxNode)", new String[]{"bn", "boxnode"}));
                int returnVal = filechooser.showOpenDialog(MainFrame.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = filechooser.getSelectedFile();
                    controller.getSelectedGraphicView().notifyObservers(new ImportBoxNodeCommand(file));
                }
            }
        });

        menuFile.add(mItemNew);
        menuFile.add(mItemOpen);
        menuFile.add(mItemSaveAs);
        menuFile.addSeparator();
        menuFile.add(mItemJPG);
        menuFile.addSeparator();
        menuFile.add(mItemExit);

        menuEdit.add(mItemModifySkin);
        menuEdit.add(mItemModifyDelay);

        menuPalette.add(mItemLoad);
        menuPalette.add(mItemBoxLoad);

        menuHelp.add(mItemHelp);
        menuHelp.add(mItemAbout);

        menubar.add(menuFile);
        menubar.add(menuEdit);
        menubar.add(menuPalette);
        menubar.add(menuHelp);
        this.setJMenuBar(menubar);
    }

    private void initGraphicView() {
        controller.addViewTab(LabelReader.getInstance().getString("mainpanel"), scroll,false);
        maingraphic.add(controller.getViewtabs(), BorderLayout.CENTER);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.X_AXIS));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    public void mouseDragged(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        this.setSize(new Dimension(this.getWidth() + x, this.getHeight() + y));
    }

    public void mouseMoved(MouseEvent e) {
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
